package com.zx.zxpicture.domain.picture.stratege;

import cn.hutool.core.util.StrUtil;
import com.zx.zxpicture.infrstructure.common.ErrorCode;
import com.zx.zxpicture.infrstructure.exception.BusinessException;
import com.zx.zxpicture.interfaces.dto.picture.PictureUploadByBatchRequest;
import com.zx.zxpicture.interfaces.dto.picture.PictureUploadRequest;
import com.zx.zxpicture.domain.user.entity.User;
import com.zx.zxpicture.interfaces.vo.PictureVO;
import com.zx.zxpicture.application.service.PictureApplicationService;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.jsoup.Jsoup;
import org.jsoup.nodes.Document;
import org.jsoup.nodes.Element;
import org.jsoup.select.Elements;

import java.io.IOException;

/**
 * 大量抓取图片上传策略
 */
@Slf4j
@RequiredArgsConstructor
public class LargeUploadByBatch implements UploadByBatchStrategy{
    private final PictureApplicationService pictureApplicationService;
    @Override
    public Integer uploadPictureByBatch(PictureUploadByBatchRequest pictureUploadByBatchRequest, User loginUser) {
        //1.获取抓取参数
        String searchText = pictureUploadByBatchRequest.getSearchText();
        Integer count = pictureUploadByBatchRequest.getCount();
        String namePrefix = pictureUploadByBatchRequest.getNamePrefix();
        if(StrUtil.isBlank(searchText)){
            throw new BusinessException(ErrorCode.PARAMS_ERROR,"搜索词不能为空");
        }
        if(count > 100){
            throw new BusinessException(ErrorCode.PARAMS_ERROR,"抓取图片数量不能超过100张");
        }
        if(StrUtil.isBlank(namePrefix)){
            namePrefix = searchText;
        }
        Integer uploadCount = 0; //记录成功拉取的图片数量
        Integer first = pictureUploadByBatchRequest.getFirst();//从多少条开始抓
        while (uploadCount < count){
            // 要抓取的地址
            String fetchUrl = String.format("https://cn.bing.com/images/async?q=%s&first=%s&mmasync=1",searchText,first);
            first += 30;
            Document document;
            try {
                //2.请求图片接口，获取网页数据
                document = Jsoup.connect(fetchUrl).get();
            } catch (IOException e) {
                log.error("获取网页失败",e);
                throw new BusinessException(ErrorCode.OPERATION_ERROR, "获取页面失败");
            }
            //3.解析网页内容
            Element div = document.getElementsByClass("dgControl").first();
            if(div == null){
                throw new BusinessException(ErrorCode.OPERATION_ERROR, "获取元素失败");
            }
            Elements imgList = div.select("img.mimg");
            //4.将图片存储到COS
            for (Element img : imgList) {
                if (uploadCount >= count) {
                    break;
                }
                //校验图片
                String fileUrl = img.attr("src");
                if (StrUtil.isBlank(fileUrl)) {
                    log.info("当前链接为空，已跳过: {}", fileUrl);
                    continue;
                }
                //因为图片路径?后面的参数非常乱，上传到COS中有可能会进行转义，导致上传报错，而且后面的参数也会影响图片质量，所以我们要处理掉?后面的参数
                int index = fileUrl.indexOf("?");
                fileUrl = fileUrl.substring(0, index);
                //5.上传图片
                PictureUploadRequest pictureUploadRequest = new PictureUploadRequest();
                pictureUploadRequest.setType("url"); //选择上传类型
                pictureUploadRequest.setPicName(namePrefix + (uploadCount+1)); //设置图片名字
                try {
                    PictureVO pictureVO = pictureApplicationService.uploadPicture(fileUrl, pictureUploadRequest, loginUser);
                    log.info("图片上传成功, id = {}", pictureVO.getId());
                    uploadCount++;
                } catch (Exception e) {
                    log.error("图片上传失败", e);
                    continue;
                }
            }
            //睡一会
            try {
                Thread.sleep(20);
            } catch (InterruptedException e) {
                throw new RuntimeException(e);
            }
        }
        return uploadCount;
    }
}
